Skip to content

03 数据类型和类型转换

数据类型

计算机世界中的万事成物都是数据。

计算机程序可以处理大量的数据,为了方便数据的管理,将数据分成了不同的类型。通过 typeof 关键字检测数据类型。

js
// 检测 1 是什么类型数据,结果为 number
document.write(typeof 1);

为什么要给数据分类

计算机程序可以处理大量的数据,为什么要给数据分类?

  1. 更加充分和高效的利用内存
  2. 也更加方便程序员的使用数据

JS 数据类型整体分为两大类:

  • 基本数据类型
    • number 数字型
    • string 字符串型
    • boolean 布尔型
    • undefined 未定义型
    • null 空类型
  • 引用数据类型

数字类型 Number

数字类型(Number)表示数字值。数字可以是整数或浮点数。JavaScript 使用 IEEE 754 标准定义的 64 位双精度浮点数来表示数字。

js
let score = 100 // 正整数
let price = 12.345 // 小数
let temperature = -40 // 负数

document.write(typeof score) // 结果为 number
document.write(typeof price) // 结果为 number
document.write(typeof temperature) // 结果为 number

JavaScript 中的数值类型与数学中的数字是一样的,分为正数、负数、小数等。

注意事项

  • JS 是弱数据类型,变量到底属于那种类型,只有赋值之后,我们才能确认
  • Java 是强数据类型 例如 int a = 3; a 必须是整数

在 JavaScript 中,有一些特殊的数字值:

  • Infinity:表示正无穷大,在数值计算中可能会出现。
  • -Infinity:表示负无穷大。
  • NaN:表示一个非数字值。当某个操作返回 NaN 时,通常意味着该操作无法生成有效的结果。

JavaScript 数字类型支持基本的算术运算,包括加、减、乘、除和取模等运算符。此外,还提供了一些内置方法,如 Math.sqrt()Math.pow()Math.round() 等。

JavaScript 中数字类型的最大值和最小值可以通过 Number.MAX_VALUENumber.MIN_VALUE 常量获得。同时还可以使用 Number.POSITIVE_INFINITYNumber.NEGATIVE_INFINITY 常量表示正无穷大和负无穷大。

注意事项

InfinityNaN 都属于 JavaScript 数字类型中的特殊值,有时候也可能会在程序中出现。在进行数学运算时,需要避免产生这些特殊值,以免导致错误的结果。

Infinity 无穷大

Infinity 表示正无穷大。它是一个特殊的数值类型,表示某些数学运算的结果超出了 JavaScript 数字类型所能表示的范围。

例如,当使用除法运算符 / 计算一个数除以 0 时,会得到 Infinity-Infinity(负无穷大)的结果。另外,如果一个数的绝对值太大超出了 JavaScript 数字类型的表示范围,也会被认为是 Infinity 值。

Infinity 可以被视为一种特殊的正常数值,可以与其他数值进行计算。

js
console.log(Infinity + 1); // 输出 Infinity
console.log(Infinity * 2); // 输出 Infinity
console.log(1 / Infinity); // 输出 0

NaN 非数字值

NaN 表示一个非数字值(Not a Number)。当某个操作返回 NaN 时,通常意味着该操作无法生成有效的结果。

  • NaN 代表一个计算错误。它是一个不正确的或者一个未定义的数学操作所得到的结果。例如:console.log("hello"/2) // NaN

  • NaN 是粘性的。任何对 NaN 的操作都会返回 NaN。例如:console.log(NaN + 2) // NaN

NaN 是一个特殊的数字值,它和任何值都不相等,包括它本身。也就是说,NaN === NaN 的结果为 false。因此,可以使用全局函数 isNaN() 来检查一个值是否为 NaN。如果传入的参数是一个非数字值或不能转换为数字,则 isNaN() 返回 true,否则返回 false

需要注意的是,虽然 NaN 通常表示一个非数字值,但也有一些情况下会返回 NaN,而这些操作本质上是可以计算出结果的。比如:

  • 对于 0/0Infinity/Infinity 这样的数学运算;
  • 对于字符串运算中包含非数字字符的情况,如 "hello"/2 或者 parseInt("abc")

实际开发

  • 在实际开发中,我们需要谨慎地处理 NaN 值,避免由于 NaN 的存在导致程序错误。例如,对于一些可能返回 NaN 的运算,应该首先判断其是否为 NaN,再进行后续操作。
  • 可以使用 isNaN() 函数或者 ES6 新增的 Number.isNaN() 来判断一个值是否为 NaN,避免因类型不匹配而出现错误。

字符串类型 string

  1. JavaScript 中什么样数据我们知道是字符串类型?
    只要用单引号、双引号、反引号包含起来的就是字符串类型

  2. 字符串拼接比较麻烦,我们可以使用什么来解决这个问题?
    模板字符串,可以让我们拼接字符串更简便

    js
    // document.write('大家好,我叫' + name + ',今年' + age + '岁')
    document.write(大家好我叫${name},今年${age})
  3. 模板字符串使用注意事项:

    • 用什么符号包含数据?反引号`
    • 用什么来使用变量?${变量名}

通过单引号( '') 、双引号( "")或反引号( ` )包裹的数据都叫字符串,单引号和双引号没有本质上的区别,推荐使用单引号。

注意事项

  1. 无论单引号或是双引号必须成对使用
  2. 单引号/双引号可以互相嵌套,但是不以自已嵌套自已(口诀:外双内单,或者外单内双)
  3. 必要时可以使用转义符 \,输出单引号或双引号
js
let user_name = "小明"; // 使用单引号
let gender = "男"; // 使用双引号
let info = "${user_name} gender ${gender}.";

let str = "123"; // 看上去是数字,但是用引号包裹了就成了字符串了
let str1 = ""; // 这种情况叫空字符串

documeent.write(typeof user_name); // 结果为 string
documeent.write(typeof gender); // 结果为 string
documeent.write(typeof str); // 结果为 string

字符串内置方法

JavaScript 中的字符串有很多内置方法,可以用来操作和处理字符串。以下是一些常用的字符串方法:

  • charAt(index):返回指定位置的字符。
  • concat(str1, str2…):将两个或多个字符串连接起来。
  • indexOf(searchValue[, startIndex]):返回字符串中第一次出现指定值的位置。
  • lastIndexOf(searchValue[, startIndex]):返回字符串中最后一次出现指定值的位置。
  • replace(searchValue, replaceValue):替换字符串中的指定值。
  • slice(startIndex[, endIndex]):提取字符串的一部分,并返回一个新的字符串。
  • split(separator[, limit]):将字符串分割成子字符串数组。
  • substr(startIndex[, length]):从指定位置开始截取字符串的指定长度。
  • substring(startIndex[, endIndex]):提取字符串的一部分,并返回一个新的字符串。
  • toLowerCase():将字符串转换为小写。
  • toUpperCase():将字符串转换为大写。

字符串拼接

  1. 使用加号 +:可以使用加号 + 来拼接两个或多个字符串。

    js
    let str1 = "Hello, ";
    let str2 = "world!";
    let result = str1 + str2;
    
    // 输出 "Hello, world!"
    console.log(result);

    注意事项

    使用加号 + 进行字符串拼接时,如果其中一个操作数是字符串,那么另一个操作数会被自动转换为字符串类型。

  2. 使用模板字符串:模板字符串是一种新的字符串语法,它使用反引号 ` 包裹字符串内容,并且可以在字符串中插入变量和表达式。

    js
    let name = "Alice";
    let age = 20;
    let result = `My name is ${name} and I am ${age} years old.`;
    
    // 输出 "My name is Alice and I am 20 years old."
    console.log(result);

    在模板字符串中,使用 ${} 语法来插入变量和表达式。

    注意事项

    模板字符串只在较新版本的浏览器中支持,如果需要兼容旧版浏览器,可以使用 babel 等工具进行转译。

  3. 使用数组 join() 方法:可以将多个字符串放到一个数组中,然后使用 join() 方法将它们拼接起来。

    js
    let arr = ["Hello", ", ", "world", "!"];
    let result = arr.join("");
    console.log(result); // 输出 "Hello, world!"

    注意事项

    join() 方法会将数组中的每个元素转换为字符串,并在它们之间插入指定的分隔符。如果不想使用分隔符,可以将分隔符设置为空字符串。

布尔类型 boolean

  1. 布尔数据类型有几个值?
    true 和 false

表示肯定或否定时在计算机中对应的是布尔类型数据,它有两个固定的值 truefalse,表示肯定的数据用 true,表示否定的数据用 false

js
//  pink 老师帅不帅?回答 是 或 否
let isCool = true; // 是的,摔死了!
isCool = false; // 不,套马杆的汉子!

document.write(typeof isCool); // 结果为 boolean

JavaScript 中的所有变量都具有 " 真实(truthy)" 或 " 虚假(falsy)" 值。当变量被用作条件时,它们会自动转换为布尔值,并且根据其真实或虚假性决定程序流程。

以下是 JavaScript 中视为 " 虚假 " 的值:

  • false
  • 0(零)
  • ""(空字符串)
  • null
  • undefined
  • NaN

除此之外的所有值都被视为 " 真实 "。

可以使用逻辑运算符(&&,||和!)来操作布尔类型的变量以及其他值,并根据需要将它们转换为布尔值。

js
var myString = "hello";
var myNumber = 42;

console.log(!!myString); // 输出:true
console.log(!myNumber); // 输出:false
console.log(myString && myNumber); // 输出:42
console.log(myString || myNumber); // 输出:"hello"

未定义类型 undefined

  1. 什么时候出现未定义数据类型?以后开发场景是?
    定义变量未给值就是 undefined
    如果检测变量是 undefined 就说明没有值传递过来

未定义是比较特殊的类型,只有一个值 undefined,只声明变量,不赋值的情况下,变量的默认值为 undefined,一般很少【直接】为某个变量赋值为 undefined

js
// 只声明了变量,并末赋值
var myVariable;
console.log(myVariable); // 输出:undefined

// 将变量显式设置为 undefined 来将其重置为未定义状态
var myVariable = "hello";
myVariable = undefined;
console.log(myVariable); // 输出:undefined

注意

  • JavaScript 中变量的值决定了变量的数据类型。

  • undefined 不同于 nullundefined 表示变量没有被赋值,而 null 表示变量的值为空。

  • 在访问对象属性时,如果该属性不存在,则返回 undefined

    js
    var myObject = {name: "John", age: 30};
    console.log(myObject.address); // 输出:undefined
  • 在函数中,如果未指定返回值,则默认返回 undefined

    js
    function doSomething() {
      // 没有返回值
    }
    console.log(doSomething()); // 输出:undefined

工作中的使用场景

  • 我们开发中经常声明一个变量,等待传送过来的数据。在使用变量之前应始终检查它们的值是否已定义。如果不这样做,可能会导致意外的行为或错误。
  • 如果我们不知道这个数据是否传递过来,此时我们可以通过检测这个变量是不是 undefined,就判断用户是否有数据传递过来。
js
var myVariable;
if (typeof myVariable === "undefined") {
  console.log("myVariable is not defined");
} else {
  console.log("myVariable is defined");
  // 业务数据处理......
}

空类型 null

  1. null 是什么类型?开发场景是?
    空类型
    如果一个变量里面确定存放的是对象,如果还没准备好对象,可以放个 null

JavaScript 中的 null 仅仅是一个代表 " 无 "、" 空 " 或 " 值未知 " 的特殊值。

js
var myVar = null; // myVar 被赋值为 null,因此它表示一个空对象指针,没有任何值

console.log(myVar); // null

null 和 undefined 区别

  • undefined 表示没有赋值
  • null 表示赋值了,但是内容为空

null 开发中的使用场景

  • 官方解释:把 null 作为尚未创建的对象
  • 大白话:将来有个变量里面存放的是一个对象,但是对象还没创建好,可以先给个 null

注意事项

如果要检查一个变量是否为 nullundefined,最好使用严格相等运算符(===),因为它不会进行类型转换。

检测数据类型

控制台输出语句

  • 控制台语句经常用于测试结果来使用。
  • 数字型和布尔型颜色为蓝色,字符串和 undefined 颜色为灰色
js
let age = 18;
let uname = "刘德华";
let flag = false;
let buy;

console.log(age); // 18,颜色为蓝色
console.log(uname); // 刘德华,颜色为灰色
console.log(flag); // false,颜色为蓝色
console.log(buy); // undefined,颜色为灰色

检测数据类型

typeof 运算符可以返回被检测的数据类型。它支持两种语法形式:

  1. 作为运算符: typeof x (常用的写法)

  2. 函数形式: typeof(x)

换言之,有括号和没有括号,得到的结果是一样的,所以我们直接使用运算符的写法。

js
let age = 18;
let uname = "刘德华";
let flag = false;
let buy;

console.log(typeof age); // number
console.log(typeof uname); // string
console.log(typeof flag); // boolean
console.log(typeof buy); // undefined

类型转换

理解弱类型语言的特征,掌握显式类型转换的方法

在 JavaScript 中数据被分成了不同的类型,如数值、字符串、布尔值、undefined,在实际编程的过程中,不同数据类型之间存在着转换的关系。

为什么需要类型转换

  • JavaScript 是弱数据类型:JavaScript 也不知道变量到底属于那种数据类型,只有赋值了才清楚。
  • 坑:使用表单、prompt 获取过来的数据默认是字符串类型的,此时就不能直接简单的进行加法运算。
  • 此时需要转换变量的数据类型。通俗来说,就是把一种数据类型的变量转换成我们需要的数据类型。

隐式转换

某些运算符被执行时,系统内部自动将数据类型进行转换,这种转换称为隐式转换。

规则:

  • + 号两边只要有一个是字符串,都会把另外一个转成字符串
  • 除了 + 以外的算术运算符 比如 - * / 等都会把数据转成数字类型

缺点:转换类型不明确,靠经验才能总结

小技巧:

  • + 号作为正号解析可以转换成数字型
  • 任何数据和字符串相加结果都是字符串
js
let num = 13; // 数值
let num2 = "2"; // 字符串

// 结果为 132
// 原因是将数值 num 转换成了字符串,相当于 '13'
// 然后 + 将两个字符串拼接到了一起
console.log(num + num2);

// 结果为 11
// 原因是将字符串 num2 转换成了数值,相当于 2
// 然后数值 13 减去 数值 2
console.log(num - num2);

let a = prompt("请输入一个数字");
let b = prompt("请再输入一个数字");

alert(a + b);

字符串与数字之间的隐式转换

在数学计算中,如果一个操作数是字符串,另一个是数字,则 JavaScript 会将字符串隐式转换为数字。

js
var num = 123 + "456"; // 等价于 var num = 123 + Number("456")
console.log(num); // 输出 123456

在比较运算(如 ==!=<> 等)中,如果一个操作数是字符串,另一个是数字,则 JavaScript 会将字符串隐式转换为数字。需要注意的是,如果字符串不能被解析成数字,隐式转换会返回 NaN。

js
"11" > 2; // 等价于 Number("11") > 2

布尔值与其他数据类型之间的隐式转换

在逻辑运算(如 &&|| 等)和条件语句(如 ifwhile 等)中,JavaScript 会将其他数据类型隐式转换为布尔值。

js
if ("hello") {
  // 等价于 if (Boolean("hello"))
  console.log("true");
}

需要注意的是,以下七个值会被转换为 false,其他值都会被转换为 true

  • false
  • undefined
  • null
  • 0
  • NaN
  • 空字符串("")
  • 布尔值 false

对象与原始类型之间的隐式转换

在算术运算、比较运算和条件语句中,JavaScript 会将对象隐式转换为原始类型。这个过程中,JavaScript 会调用对象的 valueOf()toString() 方法来获取原始值。

js
var obj = {
  valueOf: function () {
    return 123;
  },
};
console.log(obj + 456); // 等价于 Number(obj) + 456

需要注意的是,如果对象既有 valueOf() 方法,又有 toString() 方法,JavaScript 优先调用 valueOf() 方法。

模板字符串的拼接的使用

JavaScript 模板字符串是一种方便的方法来创建字符串,它允许您在字符串中嵌入表达式、变量和函数调用。模板字符串使用反引号(`)作为字符串的定界符,而不是单引号或双引号。

js
const name = "John"; // 定义变量 name
const age = 30; // 定义变量 age
const greeting = `Hello, my name is ${name} and I am ${age} years old.`; // 创建一个包含表达式的模板字符串。`${}`语法用于嵌入表达式,其中`${name}`和`${age}`代表相应变量的值。

// 输出:Hello, my name is John and I am 30 years old.
console.log(greeting);

在模板字符串中嵌入函数调用等其他 JavaScript 表达式。

js
const numbers = [1, 2, 3]; // 定义了一个简单的数组
const doubles = numbers.map((n) => n * 2); // 一个将每个元素乘以 2 的映射函数
const message = `The doubles of the numbers are: ${doubles.join(", ")}`; // 使用模板字符串将这些新值插入到消息中,使用`join()`方法将数组转换为字符串。

// 输出:The doubles of the numbers are: 2, 4, 6
console.log(message);

显式转换

编写程序时过度依靠系统内部的隐式转换是不严禁的,因为隐式转换规律并不清晰,大多是靠经验总结的规律。为了避免因隐式转换带来的问题,通常根逻辑需要对数据进行显示转换。

转换为数字型 Number

通过 Number 显示转换成数值类型,当转换失败时结果为 NaN(Not a Number)即不是一个数字。

  • Number(数据)

    • 转成数字类型
    • 如果字符串内容里有非数字,转换失败时结果为 NaN(Not a Number)即不是一个数字
    • NaN 也是 number 类型的数据,代表非数字
  • parseInt(数据):只保留整数

  • parseFloat(数据):可以保留小数

js
let t = "12";
let f = 8;

// 显式将字符串 12 转换成数值 12
t = Number(t);

// 检测转换后的类型
// console.log(typeof t);
console.log(t + f); // 结果为 20

// 并不是所有的值都可以被转成数值类型
let str = "hello";
// 将 hello 转成数值是不现实的,当无法转换成
// 数值时,得到的结果为 NaN(Not a Number)
console.log(Number(str));
js
parseInt("123"); // 123
parseFloat("3.14"); // 3.14

// 如果字符串不能被解析为数字,则会返回 NaN
parseInt("abc"); // NaN
parseFloat("xyz"); // NaN

转换为字符型 String

  • 使用 String() 函数:可以使用 String() 函数将其他数据类型转换为字符串类型。
    • 需要注意的是,String(null)String(undefined) 分别返回 "null""undefined" 字符串。
  • 使用 toString() 方法:除了 nullundefined 之外,JavaScript 中的所有值都具有 toString() 方法,调用该方法可以将值转换为字符串类型。
    • 需要注意的是,对于 nullundefined,不能直接调用 toString() 方法,否则会抛出 TypeError 异常。
js
String(123); // "123"
String(true); // "true"
String(false); // "false"
String(null); // "null"
String(undefined); // "undefined"
js
var num = 123;
num.toString(); // "123"

var arr = [1, 2, 3];
arr.toString(); // "1,2,3"

转换为布尔类型 Boolean

可以使用 Boolean() 函数将字符串转换为布尔值。

  • 如果参数是 undefinednullNaN、空字符串 ("") 或数字 0 (零),则转换后结果为 false
  • 如果参数是任何其他值(包括空对象 {} 和空数组 []),则转换后结果为 true
js
Boolean(""); // false
Boolean(0); // false
Boolean(undefined); // false
Boolean(null); // false
Boolean(NaN); // false

Boolean("hello"); // true
Boolean(42); // true
Boolean([]); // true
Boolean({}); // true

注意事项

  • 使用双等号(==)进行比较时,JavaScript 会自动将值隐式地转换为布尔类型。如果使用双等号进行比较,那么 JavaScript 会转换为布尔类型。
  • 这种行为可能会导致错误和混乱,因为它不明确指定了要转换的类型。建议始终使用三等号(===)进行比较,这样可以确保值和类型都匹配。
js
if (myVar == true) {
  // 代码块
}

// 等价于
if (myVar) {
  // 代码块
}

转换为符合 JSON 格式的字符串

JSON.stringify() 是 JavaScript 中的一个方法,用于将 JavaScript 对象或数组转换为符合 JSON 格式的字符串。

在使用 JSON.stringify() 方法时,可以传递三个参数:

  1. value:需要被转换为 JSON 字符串的值。
  2. replacer:可选参数,可以是函数或数组,用于控制转换过程中哪些属性需要包含在最终的 JSON 字符串中。
  3. space:可选参数,用于定义缩进字符,使生成的 JSON 字符串更易读。
js
const obj = {
  name: "John",
  age: 30,
  city: "New York",
};

const jsonString = JSON.stringify(obj);

console.log(jsonString);
// 输出结果:{"name":"John","age":30,"city":"New York"}